﻿using System;
using System.Collections.Generic;

namespace Manoso.Data.FluentMap
{
    public interface IMapAdaptor
    {
        /// <summary>
        /// Parameter name of the return value.
        /// </summary>
        string ReturnValue { get; }

        /// <summary>
        /// Prefix that indicate a parameter.
        /// </summary>
        /// <example>"@" is the prefix for parameter in TSQL.</example>
        string ParameterPrefix { get; }

        /// <summary>
        /// Convert object to sql value.
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        string Translate(object arg);

        /// <summary>
        /// Escape special charactors like single quote, carriage return.
        /// </summary>
        /// <param name="value">Value need to be checked for escape charactors.</param>
        /// <returns>String value after the escape.</returns>
        string EscapeSql(object value);

        /// <summary>
        /// Get Sql declare statement of the given type and name.
        /// </summary>
        /// <param name="type">Type of the parameter.</param>
        /// <param name="name">Name of the parameter.</param>
        /// <returns>The Sql declaration statement.</returns>
        string GetDeclare(Type type, string name);

        /// <summary>
        /// Get Sql assignment statement to set the last insert identity to the column. 
        /// </summary>
        /// <param name="idColumn">The Id column will be set.</param>
        /// <returns>The Sql assignment statement.</returns>
        string GetIdentity(string idColumn);

        /// <summary>
        /// Get Sql assignment statement to column value. 
        /// </summary>
        /// <param name="column">The column will be set.</param>
        /// <returns>The Sql assignment statement.</returns>
        string GetAssignment(IMapColumn column);

        /// <summary>
        /// Get Sql Insert statement for all columns of the given table, using columns and values.
        /// </summary>
        /// <param name="table">Table name.</param>
        /// <param name="columns">A list of one or more columns in which to insert data.</param>
        /// <returns>The Sql Insert statement.</returns>
        string GetInsert(string table, IEnumerable<IMapColumn> columns);

        /// <summary>
        /// Get Sql Update statement using the given table, columns, values, idColumns and idValues.
        /// </summary>
        /// <param name="table">Table name.</param>
        /// <param name="idColumns">IMapColumn collection of the columns for the Where clause.</param>
        /// <param name="columns">A list of one or more columns upon which to update data.</param>
        /// <returns>The Sql Update statement.</returns>
        string GetUpdate(string table, IEnumerable<IMapColumn> idColumns, IEnumerable<IMapColumn> columns);

        /// <summary>
        /// Get Sql Delete statement using the given table, idColumns and idValues.
        /// </summary>
        /// <param name="table">Table name.</param>
        /// <param name="idColumns">IMapColumn collection of the columns for the Where clause.</param>
        /// <returns>The Sql Delete statement.</returns>
        string GetDelete(string table, IEnumerable<IMapColumn> idColumns);

        /// <summary>
        /// Get Sql statement to execute the sotre procedure.
        /// </summary>
        /// <param name="storeProc">The store procudure name.</param>
        /// <param name="columns">A list of one or more columns used as store procedure parameters.</param>
        /// <returns>The Execute statement for the store procedure.</returns>
        string GetExec(string storeProc, IEnumerable<IMapColumn> columns);

        /// <summary>
        /// Get Sql statement to execute the sotre procedure and set given id column with the return value.
        /// </summary>
        /// <param name="storeProc">The store procedure name.</param>
        /// <param name="idColumn">The Id column that store procedure return value is set upon.</param>
        /// <param name="columns">A list of one or more columns used as store procedure parameters.</param>
        /// <returns>The Execute statement for the store procedure.</returns>
        string GetExecReturn(string storeProc, string idColumn, IEnumerable<IMapColumn> columns);

        /// <summary>
        /// Get a return select statement.
        /// </summary>
        /// <param name="table">Name of the table.</param>
        /// <param name="alias">Alias of the table.</param>
        /// <param name="columns">IMapColumn collection of all the returning columns.</param>
        /// <param name="idColumn">IMapColumn object for the primary key column.</param>
        /// <returns>The Select statement returns a column.</returns>
        string GetReturn(string table, string alias, IEnumerable<IMapColumn> columns, IMapColumn idColumn);

        /// <summary>
        /// Get the Left Join clause.
        /// </summary>
        /// <param name="tableSource">Joining/Right table name.</param>
        /// <param name="aliasSource">Joining/Right table alias.</param>
        /// <param name="aliasTarget">Alias of the left table.</param>
        /// <param name="onSource">Evaluating columns of the joining/right table.</param>
        /// <param name="onTarget">Evaluating columns of the left table.</param>
        /// <returns></returns>
        string GetLeftJoin(string tableSource, string aliasSource, string aliasTarget, IEnumerable<string> onSource,
            IEnumerable<string> onTarget);

        /// <summary>
        /// Get sql select statement with left joins.
        /// </summary>
        /// <param name="fromTable">The starting from table name.</param>
        /// <param name="fromAlias">The starting from table alias.</param>
        /// <param name="where">The where clause.</param>
        /// <param name="columns">Returned column names.</param>
        /// <param name="joins">Given left joins.</param>
        /// <returns></returns>
        string GetSelect(string fromTable, string fromAlias, string where, IEnumerable<IMapColumn> columns, IEnumerable<string> joins);
    }
}

